package com.hcms.common.customtag.menua;

import com.hcms.system.dao.AdminRoleDao;
import com.hcms.system.dao.MenuDao;
import com.hcms.system.dao.RoleDao;
import com.hcms.system.dao.RoleMenuDao;
import com.hcms.system.domain.*;
import com.hcms.system.service.MenuService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.thymeleaf.context.ITemplateContext;
import org.thymeleaf.model.IModel;
import org.thymeleaf.model.IModelFactory;
import org.thymeleaf.model.IProcessableElementTag;
import org.thymeleaf.processor.element.AbstractElementTagProcessor;
import org.thymeleaf.processor.element.IElementTagStructureHandler;
import org.thymeleaf.spring5.context.SpringContextUtils;
import org.thymeleaf.templatemode.TemplateMode;

import java.util.List;
import java.util.stream.Collectors;

// 自定义标签构建类
// 权限按钮 a 链接
public class MenuATagProcessor extends AbstractElementTagProcessor {

    // 标签名
    private static final String TAG_NAME = "a";

    // 优先级
    private static final int PRECEDENCE = 10000;

    public MenuATagProcessor(String dialectPrefix) {
        super(
                TemplateMode.HTML,  // 模板类型为：HTML
                dialectPrefix,      // 标签方言前缀
                TAG_NAME,           // 标签名称
                true,               // 将标签前缀应用于标签名称
                null,               // 无属性名称：将通过标签名称匹配
                false,              // 没有要应用于属性名称的前缀
                PRECEDENCE          // 优先级
        );
    }

    /**
     * 处理自定义标签 DOM 结构
     *
     * @param iTemplateContext            模板页上下文
     * @param iProcessableElementTag      待处理标签
     * @param iElementTagStructureHandler 元素标签结构处理器
     */
    @Override
    protected void doProcess(ITemplateContext iTemplateContext, IProcessableElementTag iProcessableElementTag, IElementTagStructureHandler iElementTagStructureHandler) {
        // 获取 Spring 上下文
        ApplicationContext applicationContext = SpringContextUtils.getApplicationContext(iTemplateContext);
        // 获取注入 bean 工厂
        AutowireCapableBeanFactory autowireCapableBeanFactory = applicationContext.getAutowireCapableBeanFactory();
        // 获取所需的 bean
        MenuService menuService = autowireCapableBeanFactory.getBean(MenuService.class);

        Boolean isShow = true;

        // 标签的 权限 名称 属性
        String permsName = iProcessableElementTag.getAttributeValue("perms-name");

        // 是否小型按钮
        boolean isSmall = iProcessableElementTag.hasAttribute("small");

        MenuDo menuDo = null;

        if (permsName == null) {
            isShow = false;
        } else {
            menuDo = menuService.getByPermsName(permsName);

            if (menuDo != null) {
                isShow = isAllowCreate(permsName, autowireCapableBeanFactory);
            }
        }

        StringBuffer result = createHtml(isShow, menuDo, permsName, isSmall);

        // 创建将替换自定义标签的 DOM 结构
        IModelFactory modelFactory = iTemplateContext.getModelFactory();
        IModel model = modelFactory.createModel();
        // 将字典的内容拼装成一个 A 链接
        model.add(modelFactory.createText(result));
        // 利用引擎替换整合标签
        iElementTagStructureHandler.replaceWith(model, false);
    }

    // 创建 Html
    private StringBuffer createHtml(Boolean isShow, MenuDo menuDo, String permsName, boolean isSmall) {
        StringBuffer result = new StringBuffer("");

        // 没找到权限配置，不显示
        if (!isShow || menuDo == null) {
            result.append("");
        }
        // 构建 DOM
        else {
            String[] permsNameArray = permsName.split(":");
            String eventName = permsNameArray[permsNameArray.length - 1];

            String aClassName = "layui-btn";
            if (isSmall) {
                aClassName += " layui-btn-xs";
            }

            result.append("<a class=\"" + aClassName + "\" lay-event=\"" + eventName + "\">");
            if (menuDo.getIcon() != "") {

                String iClassName = "layui-icon " + menuDo.getIcon();

                result.append("<i class=\"" + iClassName + "\"></i>");
            }
            result.append(menuDo.getName());
            result.append("</a>");
        }
        return result;
    }

    // 判断登录用户权限
    private boolean isAllowCreate(String permsName, AutowireCapableBeanFactory autowireCapableBeanFactory) {
        boolean result = false;

        // 1、获取当前登录用户
        Subject subject = SecurityUtils.getSubject();
        AdminDo currentAdmin = (AdminDo) subject.getPrincipal();
        if (currentAdmin == null || currentAdmin.getMarkStatus() != 0) {
            return false;
        }

        AdminRoleDao adminRoleDao = autowireCapableBeanFactory.getBean(AdminRoleDao.class);
        // 2、获取用户角色
        AdminRoleDo adminRole = adminRoleDao.getByAdmin(currentAdmin.getId());
        if (adminRole == null || adminRole.getMarkStatus() != 0) {
            return false;
        }

        RoleDao roleDao = autowireCapableBeanFactory.getBean(RoleDao.class);
        // 3、判断角色信息是否正常
        RoleDo roleDo = roleDao.get(adminRole.getRoleId());
        if (roleDo == null || roleDo.getMarkStatus() != 0) {
            return false;
        }

        RoleMenuDao roleMenuDao = autowireCapableBeanFactory.getBean(RoleMenuDao.class);
        // 4、获取角色菜单
        List<RoleMenuDo> roleMenuDos = roleMenuDao.listByRoleId(adminRole.getRoleId())
                .stream()
                .filter(t -> t.getMarkStatus() == 0)
                .collect(Collectors.toList());
        if (roleMenuDos == null || roleMenuDos.size() == 0) {
            return false;
        }

        MenuDao menuDao = autowireCapableBeanFactory.getBean(MenuDao.class);
        // 5、获取菜单授权标识
        for (RoleMenuDo roleMenuDo : roleMenuDos) {
            String perms = menuDao.findPermsByMenuId(roleMenuDo.getMenuId());
            if (perms != "" && perms.equalsIgnoreCase(permsName)) {
                result = true;
                break;
            }
        }

        return result;
    }
}
